package com.m4f.business.security;

import java.util.HashSet;
import java.util.Set;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import com.m4f.business.model.Company;
import com.m4f.business.model.Participant;
import com.m4f.business.service.ifc.ICompanyService;
import org.springframework.security.authentication.encoding.Md5PasswordEncoder;

public class InternalUserDetailService implements UserDetailsService {
	
	private ICompanyService companyService;
	private static Participant root;
	
	public InternalUserDetailService(String rootUser, 
			String rootPassword, ICompanyService compService) {
		root = new Participant();
		root.setEmail(rootUser);
		root.setPassword(rootPassword);
		this.companyService = compService;
	}
	
	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException, DataAccessException {
		if(root.getEmail().equals(username)) {
			return makeRootUser(root);
		}
		Company company = this.companyService.getCompanyByParticipant(username);
		if(company == null ) {
			throw new UsernameNotFoundException("User not found: " + username);
		}
		Participant user = company.getParticipantInfo();
		if (user == null)
			throw new UsernameNotFoundException("User not found: " + username);
		else {
			return makeUser(user);
		}
	}
	
	private UserDetails makeRootUser(Participant user) {
		Object salt = null;
		Md5PasswordEncoder encoder = new Md5PasswordEncoder();
		return new User(user.getEmail(), encoder.encodePassword(user.getPassword(), salt), 
				true, true, true, true, makeRootGrantedAuthorities(user.getClass()));
	}

	private java.util.Collection<GrantedAuthority> makeRootGrantedAuthorities(Class userClass) {
		java.util.Collection<GrantedAuthority> authorities = 
				new java.util.ArrayList<GrantedAuthority>();
		Set<String> roles = new HashSet<String>(); 
	    roles.add("ROLE_USER");        
	    roles.add("ROLE_COMPANY_SUPERVISOR");
		for (String role : roles) {
			authorities.add(new GrantedAuthorityImpl(role));
		}
		return authorities;
	}
	
	private UserDetails makeUser(Participant user) {
		Object salt = null;
		Md5PasswordEncoder encoder = new Md5PasswordEncoder();
		return new User(user.getEmail(), encoder.encodePassword(user.getPassword(), salt), 
				true, true, true, true, makeGrantedAuthorities(user.getClass()));
	}

	private java.util.Collection<GrantedAuthority> makeGrantedAuthorities(Class userClass) {
		java.util.Collection<GrantedAuthority> authorities = 
				new java.util.ArrayList<GrantedAuthority>();
		Set<String> roles = new HashSet<String>(); 
	    roles.add("ROLE_USER");        
	    roles.add("ROLE_COMPANY");
		for (String role : roles) {
			authorities.add(new GrantedAuthorityImpl(role));
		}
		return authorities;
	}

}
